package org.jeecg.modules.kc.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.ObjectUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.kc.entity.KcDepositoryInGoods;
import org.jeecg.modules.kc.entity.KcStock;
import org.jeecg.modules.kc.entity.KcStockDetail;
import org.jeecg.modules.kc.entity.KcSupplierInGoods;
import org.jeecg.modules.kc.mapper.KcStockMapper;
import org.jeecg.modules.kc.service.*;
import org.jeecg.modules.rooms.entity.CesGoods;
import org.jeecg.modules.rooms.entity.CesGoodsUnit;
import org.jeecg.modules.rooms.service.CesGoodsServiceImpl;
import org.jeecg.modules.rooms.service.CesGoodsUnitServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: kc_stock
 * @Author: jeecg-boot
 * @Date:   2023-04-18
 * @Version: V1.0
 */
@Service
public class KcStockServiceImpl extends ServiceImpl<KcStockMapper, KcStock> implements IKcStockService {


    @Autowired
    private IKcSupplierInGoodsService kcSupplierInGoodsService;
    @Autowired
    private IKcGoodsService kcGoodsService;
    @Autowired
    private CesGoodsUnitServiceImpl cesGoodsUnitService;
    @Autowired
    private IKcDepositoryService kcDepositoryService;
    @Autowired
    private IKcSupplierService kcSupplierService;
    @Autowired
    private IKcStockDetailService kcStockDetailService;
    @Autowired
    private  IKcDepositoryInGoodsService kcDepositoryInGoodsService;

    @Autowired
    private CesGoodsServiceImpl cesGoodsService;

    @Override
    public void add(KcStock kcStock) {
        kcStock.setTenantId(TokenUtils.currentTenantId());
        kcStock.setStatus(0);
        String prefix = "CK";
        if (kcStock.getType().equals(2)) {
            prefix = "RK";
        } else if (kcStock.getType().equals(3)) {
            prefix = "PD";
        }
        kcStock.setCode(randomNumber(prefix));
        LoginUser user = TokenUtils.getAuthUser();
        kcStock.setCreateAt(user.getRealname());
        kcStock.setCreateTime(DateTime.now());
        String stockInfo = "";
        for (KcStockDetail kcStockDetail : kcStock.getStockDetailList()) {
            if (kcStock.getType().equals(2)) {
                KcSupplierInGoods kcSupplierInGoods = kcSupplierInGoodsService.getById(kcStockDetail.getSupplierInGoodsId());
                if (kcSupplierInGoods != null) {
                    CesGoods cesGoods = cesGoodsService.getById(kcSupplierInGoods.getGoodsId());
                    if (cesGoods != null) {
                        kcStockDetail.setCesGoods(cesGoods);
                        kcStockDetail.setGoodId(cesGoods.getId());
                        CesGoodsUnit cesGoodsUnit = cesGoodsUnitService.getById(cesGoods.getGoodUnit());
                        if (cesGoodsUnit != null) {
                            stockInfo += cesGoods.getName() + kcStockDetail.getNum() + cesGoodsUnit.getName() + ",";
                        }
                    }
                }
            } else if (kcStock.getType().equals(1)||kcStock.getType().equals(3)) {

                KcDepositoryInGoods kcDepositoryInGoods = kcDepositoryInGoodsService.getById(kcStockDetail.getSupplierInGoodsId());
                if (kcDepositoryInGoods != null) {
                    CesGoods cesGoods = cesGoodsService.getById(kcDepositoryInGoods.getGoodsId());
                    if (cesGoods != null) {
                        kcStockDetail.setCesGoods(cesGoods);
                        kcStockDetail.setGoodId(cesGoods.getId());
                        CesGoodsUnit cesGoodsUnit = cesGoodsUnitService.getById(cesGoods.getGoodUnit());
                        if (cesGoodsUnit != null) {
                            stockInfo += cesGoods.getName() + kcStockDetail.getNum() + cesGoodsUnit.getName() + ",";
                        }
                    }
                }
            }
        }
        kcStock.setStockInfo(stockInfo);
        save(kcStock);
        for (KcStockDetail kcStockDetail : kcStock.getStockDetailList()) {
            kcStockDetail.setHotelId(kcStock.getHotelId());
            kcStockDetail.setTenantId(TokenUtils.currentTenantId());
            kcStockDetail.setStockId(kcStock.getCode());
            kcStockDetail.setId("");
        }
        kcStockDetailService.saveBatch(kcStock.getStockDetailList());
    }

    @Override
    public void audit(KcStock kcStock) {
        updateById(kcStock);
        if (kcStock.getStatus().equals(1)) {
            if (kcStock.getType().equals(2)) {
                LambdaQueryWrapper<KcStockDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(KcStockDetail::getStockId, kcStock.getCode());
                List<KcStockDetail> stockDetailList = kcStockDetailService.list(lambdaQueryWrapper);
                if (ObjectUtils.isNotEmpty(stockDetailList)) {
                    List<KcDepositoryInGoods> depositoryInGoodsList = new ArrayList<>();
                    List<CesGoods> goodsList = new ArrayList<>();
                    for (KcStockDetail kcStockDetail : stockDetailList) {
                        // 拿到当前仓库商品关联数据
                        KcSupplierInGoods kcSupplierInGoods = kcSupplierInGoodsService.getById(kcStockDetail.getSupplierInGoodsId());
                        if (kcSupplierInGoods != null) {
                            CesGoods cesGoods = cesGoodsService.getById(kcSupplierInGoods.getGoodsId());
                            if (cesGoods != null) {
                                kcStockDetail.setCesGoods(cesGoods);
                            }
                        }
                        if (ObjectUtils.isNotEmpty(kcStockDetail.getCesGoods())) {
                            // 有商品入库后修改商品数量,成本价设置为最后一次的进价
                            CesGoods cesGood = kcStockDetail.getCesGoods();
                            cesGood.setBid(kcStockDetail.getPrice());
                            cesGood.setInventory(cesGood.getInventory() + kcStockDetail.getNum());
                            goodsList.add(cesGood);
//							 LambdaQueryWrapper<KcDepositoryInGoods> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
//							 lambdaQueryWrapper2.eq(KcDepositoryInGoods::getDepositoryId, kcStock.getDepositoryId());
//							 lambdaQueryWrapper2.eq(KcDepositoryInGoods::getGoodsId, kcStockDetail.getCesGoods().getId());
//							 KcDepositoryInGoods kcDepositoryInGoods = kcDepositoryInGoodsService.getOne(lambdaQueryWrapper2);


//							 if (kcDepositoryInGoods != null) {
//								 kcDepositoryInGoods.setNum(kcDepositoryInGoods.getNum() + kcStockDetail.getNum());
//							 } else {
                            KcDepositoryInGoods kcDepositoryInGoods = new KcDepositoryInGoods();
                            kcDepositoryInGoods.setTenantId(kcStock.getTenantId());
                            kcDepositoryInGoods.setHotelId(kcStock.getHotelId());
                            kcDepositoryInGoods.setDepositoryId(kcStock.getDepositoryId());
                            kcDepositoryInGoods.setGoodsId(cesGood.getId());
                            kcDepositoryInGoods.setNum(kcStockDetail.getNum());
                            kcDepositoryInGoods.setStockDetailId(kcStockDetail.getId());
//							 }
                            depositoryInGoodsList.add(kcDepositoryInGoods);
                        }
                    }
                    System.out.println(depositoryInGoodsList.toString());
                    kcDepositoryInGoodsService.saveBatch(depositoryInGoodsList);
                    cesGoodsService.updateBatchById(goodsList);
                }
            } else if (kcStock.getType().equals(1)) {
                LambdaQueryWrapper<KcStockDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(KcStockDetail::getStockId, kcStock.getCode());
                // 循环的只会有一个仓库下的不同商品
                List<KcStockDetail> stockDetailList = kcStockDetailService.list(lambdaQueryWrapper);
                List<String> goodIds = stockDetailList.stream().map(KcStockDetail::getGoodId).collect(Collectors.toList());
                List<CesGoods> goodsList = cesGoodsService.listByIds(goodIds);
                List<KcDepositoryInGoods> depositoryInGoodsList = new ArrayList<>();
                if (ObjectUtils.isNotEmpty(stockDetailList)) {
                    for (KcStockDetail kcStockDetail : stockDetailList) {
                        QueryWrapper<KcDepositoryInGoods> queryWrapper = new QueryWrapper<>();
                        queryWrapper.select("SUM(num) as num");
                        queryWrapper.eq("depository_id", kcStock.getDepositoryId());
                        queryWrapper.eq("goods_id", kcStockDetail.getGoodId());
                        KcDepositoryInGoods kcDepositoryInGoodList = kcDepositoryInGoodsService.getOne(queryWrapper);
                        if (kcDepositoryInGoodList.getNum() - kcStockDetail.getNum() < 0){
                            throw new JeecgBootException("库存不足");
                        }
                        Optional<CesGoods> goodsOptional = goodsList.stream().filter(e -> e.getId().equals(kcStockDetail.getGoodId())).findFirst();
                        if (goodsOptional.isPresent()){
                            // 商品中库存是否足够
                            int differ = goodsOptional.get().getInventory() - kcStockDetail.getNum();
                            if (differ < 0){
                                throw new JeecgBootException("库存不足");
                            }
                            goodsOptional.get().setInventory(differ);
                            KcDepositoryInGoods kcDepositoryInGoods = new KcDepositoryInGoods();
                            kcDepositoryInGoods.setTenantId(kcStock.getTenantId());
                            kcDepositoryInGoods.setHotelId(kcStock.getHotelId());
                            kcDepositoryInGoods.setDepositoryId(kcStock.getDepositoryId());
                            kcDepositoryInGoods.setGoodsId(goodsOptional.get().getId());
                            kcDepositoryInGoods.setNum(-kcStockDetail.getNum());
                            kcDepositoryInGoods.setStockDetailId(kcStockDetail.getId());
                            depositoryInGoodsList.add(kcDepositoryInGoods);
                        }else {
                            throw new JeecgBootException("未找到商品");
                        }
                        cesGoodsService.updateBatchById(goodsList);
                        kcDepositoryInGoodsService.saveBatch(depositoryInGoodsList);
                    }
                }
            } else if (kcStock.getType().equals(3)) {
                LambdaQueryWrapper<KcStockDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(KcStockDetail::getStockId, kcStock.getCode());
                List<KcStockDetail> stockDetailList = kcStockDetailService.list(lambdaQueryWrapper);
                if (ObjectUtils.isNotEmpty(stockDetailList)) {
                    for (KcStockDetail kcStockDetail : stockDetailList) {
                        KcDepositoryInGoods depositoryInGoods = kcDepositoryInGoodsService.getById(kcStockDetail.getSupplierInGoodsId());
                        if (depositoryInGoods != null) {
                            if (depositoryInGoods != null) {
                                Integer num = kcStockDetail.getNum();
                                if (num < 0) num = 0;
                                depositoryInGoods.setNum(num);
                                kcDepositoryInGoodsService.updateById(depositoryInGoods);
                            }
                        }
                    }
                }
            }
        }
    }


    /**
     * 生成16位数字+prefix
     * @param prefix
     * @return
     */
    private String randomNumber(String prefix) {
        int first = new Random(10).nextInt(8) + 1;
        int hashCode = UUID.randomUUID().toString().hashCode();
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        return prefix + first + String.format("%015d", hashCode);
    }
}
